﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using InmobiliariaDatos;
using System.Collections;

namespace InmobiliariaNegocio
{
    [Serializable]
    public class Inmobiliaria
    {
        private List<Inmueble> inmuebles;
        private List<Alquiler> alquileres;
        private List<Venta> ventas;
        private List<Reserva> reservas;
        private List<Cliente> clientes;

        public List<Inmueble> Inmuebles
        {
            get { return inmuebles; }
        }

        public List<Alquiler> Alquileres
        {
            get { return alquileres; }
        }

        public List<Venta> Ventas
        {
            get { return ventas; }
        }

        public List<Reserva> Reservas
        {
            get { return reservas; }
        }

        public List<Cliente> Clientes
        {
            get { return clientes; }
        }

        public Inmobiliaria()
        {
            inmuebles = new List<Inmueble>();
            ventas = new List<Venta>();
            alquileres = new List<Alquiler>();
            reservas = new List<Reserva>();
            clientes = new List<Cliente>();
        }

        public static Inmobiliaria Recuperar()
        {
            return (Inmobiliaria)Datos.RecuperarInmobiliaria();
        }

        public bool guardar()
        {
            return Datos.GuardarInmobiliaria(this);
        }

        public string agregarInmueble(Inmueble dato)
        {
            if (buscarInmueble(dato) != null)
            {
                return "El inmueble ya existe.";
            }
            else
            {
                Inmuebles.Add(dato);
                return "Inmueble agregado correctamente.";
            }
        }

        public string agregarVenta(Venta dato)
        {
            Inmueble inmueble = this.buscarInmueble(dato.Inmueble);

            if (inmueble != null)
            {
                dato.TipoOp = "Vendido";
                Ventas.Add(dato);
                return "Venta agregada correctamente.";
            }
            else
                return "El inmueble no existe.";
        }

        public string agregarAlquiler(Alquiler dato)
        {
            Inmueble inmueble = this.buscarInmueble(dato.Inmueble);

            if (inmueble != null)
            {
                dato.TipoOp = "Alquilado";
                Alquileres.Add(dato);
                return "Alquiler agregado correctamente.";
            }
            else
                return "El inmueble no existe.";
        }

        public bool existeClienteEnAlquiler(Cliente dato)
        {
            int i = 0;

            while (i < alquileres.Count && alquileres[i].Cliente.Equals(dato))
                i++;

            if (i < alquileres.Count)
                return true;
            else
                return false;
        }

        public bool existeClienteEnVenta(Cliente dato)
        {
            int i = 0;

            while (i < ventas.Count && ventas[i].Cliente.Equals(dato))
                i++;

            if (i < ventas.Count)
                return true;
            else
                return false;
        }

        public bool eliminarReserva(int nroInm)
        {
            Reserva res = buscarReserva(nroInm);

            if (res != null)
            {
                reservas.Remove(res);
                res.eliminarseBD();
                return true;
            }
            else
                return false;
        }

        public bool existeInmuebleEnAlquiler(Inmueble dato)
        {
            int i = 0;

            while (i < alquileres.Count && !alquileres[i].Inmueble.Equals(dato.Numero))
                i++;

            if (i < alquileres.Count)
                return true;
            else
                return false;
        }

        public bool existeInmuebleEnVenta(Inmueble dato)
        {
            int i = 0;

            while (i < ventas.Count && !ventas[i].Inmueble.Equals(dato.Numero))
                i++;

            if (i < ventas.Count)
                return true;
            else
                return false;
        }

        public bool validarReserva(Reserva dato)
        {
            Inmueble inmueble = this.buscarInmueble(dato.Inmueble);

            if (inmueble.Reservado)
                return false;
            else
                return true;
        }

        public string agregarReserva(Reserva dato)
        {
            Inmueble inmueble = this.buscarInmueble(dato.Inmueble);

            if (inmueble != null)
            {
                dato.TipoOp = "Reservado";
                Reservas.Add(dato);
                return "Reserva realizada correctamente.";
            }
            else
                return "El inmueble no existe.";
        }

        public bool agregarCliente(Cliente dato)
        {
            Cliente cli = buscarCliente(dato);

            if (cli != null)
            {
                return false;
            }
            else
            {
                Clientes.Add(dato);
                return true;
            }
        }

        public void eliminarCliente(Cliente dato)
        {
            Clientes.Remove(dato);
        }

        public void modificarInmueble(int nroInmueble, bool reservado, string tipoOp)
        {
            Inmueble inm = buscarInmueble(nroInmueble);

            if (inm != null)
            {
                if (tipoOp != "")
                    inm.TipoOperacion = tipoOp;
                inm.Reservado = reservado;
                inm.modificarseBD();
            }
        }

        public List<Cliente> listarClientes()
        {
            return clientes;
        }

        public List<Inmueble> listarInmuebles()
        {
            return inmuebles;
        }
        public List<Venta> listarVentas()
        {
            return ventas;
        }
        public List<Alquiler> listarAlquileres()
        {
            return alquileres;
        }

        //Son los que no están reservados y los que no están vendidos o alquilados
        public List<Inmueble> listarInmueblesReserva()
        {
            List<Inmueble> disponibles = new List<Inmueble>();

            bool vendido = false;
            bool alquilado = false;
            bool reservado = false;

            for (int i = 0; i < inmuebles.Count; i++)
            {
                vendido = false;

                for (int j = 0; j < ventas.Count; j++)
                {
                    if (ventas[j].Inmueble.Equals(inmuebles[i].Numero))
                        vendido = true;
                }
                if (!vendido && !inmuebles[i].Reservado && (inmuebles[i].TipoOperacion.Equals("Venta") || inmuebles[i].TipoOperacion.Equals("Ambos")))
                    disponibles.Add(inmuebles[i]);
            }

            for (int i = 0; i < inmuebles.Count; i++)
            {
                alquilado = false;

                for (int j = 0; j < alquileres.Count; j++)
                {
                    if (alquileres[j].Inmueble.Equals(inmuebles[i].Numero))
                        alquilado = true;
                }
                if (!alquilado && !inmuebles[i].Reservado && inmuebles[i].TipoOperacion.Equals("Alquiler"))
                    disponibles.Add(inmuebles[i]);
            }

            return disponibles;
        }

        //Son los que no están vendidos o alquilados
        public List<Inmueble> listarInmueblesDisponibles()
        {
            List<Inmueble> disponibles = new List<Inmueble>();

            bool vendido = false;
            bool alquilado = false;
            bool reservado = false;

            for (int i = 0; i < inmuebles.Count; i++)
            {
                vendido = false;

                for (int j = 0; j < ventas.Count; j++)
                {
                    if (ventas[j].Inmueble.Equals(inmuebles[i].Numero))
                        vendido = true;
                }
                if (!vendido && !inmuebles[i].Reservado && (inmuebles[i].TipoOperacion.Equals("Venta") || inmuebles[i].TipoOperacion.Equals("Ambos")))
                    disponibles.Add(inmuebles[i]);
            }

            for (int i = 0; i < inmuebles.Count; i++)
            {
                alquilado = false;

                for (int j = 0; j < alquileres.Count; j++)
                {
                    if (alquileres[j].Inmueble.Equals(inmuebles[i].Numero))
                        alquilado = true;
                }
                if (!alquilado && !inmuebles[i].Reservado && inmuebles[i].TipoOperacion.Equals("Alquiler"))
                    disponibles.Add(inmuebles[i]);
            }

            return disponibles;
        }

        public List<Reserva> listarReservas()
        {
            return reservas;
        }

        public Inmueble buscarInmueble(Inmueble dato)
        {
            try
            {
                int i = 0;
                bool salida = false;

                while (i < Inmuebles.Count && salida != true)
                {
                    if (!Inmuebles[i].Direccion.Equals(dato.Direccion))
                        i++;
                    else if (!Inmuebles[i].Localidad.Equals(dato.Localidad))
                        i++;
                    else
                        salida = true;
                }

                if (i < Inmuebles.Count)
                    return Inmuebles[i];
                else
                    return null;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public Inmueble buscarInmueble(int dato)
        {
            int i = 0;

            while (i < Inmuebles.Count && !(Inmuebles[i].Numero == dato))
                i++;

            if (i < Inmuebles.Count)
                return Inmuebles[i];
            else
                return null;
        }

        public Alquiler buscarAlquiler(Alquiler dato)
        {
            int i = 0;

            while (i < Alquileres.Count && !Alquileres[i].Inmueble.Equals(dato.Inmueble))
                i++;

            if (i < Alquileres.Count)
                return Alquileres[i];
            else
                return null;
        }

        public Venta buscarVenta(Venta dato)
        {
            int i = 0;

            while (i < Ventas.Count && !Ventas[i].Inmueble.Equals(dato.Inmueble))
                i++;

            if (i < Ventas.Count)
                return Ventas[i];
            else
                return null;
        }

        public Reserva buscarReserva(int dato)
        {
            int i = 0;

            while (i < Reservas.Count && !Reservas[i].Inmueble.Equals(dato))
                i++;

            if (i < Reservas.Count)
                return Reservas[i];
            else
                return null;
        }

        public Cliente buscarCliente(Cliente dato)
        {
            int i = 0;

            while (i < Clientes.Count && !Clientes[i].Dni.Equals(dato.Dni))
                i++;

            if (i < Clientes.Count)
                return Clientes[i];
            else
                return null;
        }

        public Cliente buscarCliente(int dni, string clave)
        {
            int i = 0;

            while (i < Clientes.Count && !(Clientes[i].Dni.Equals(dni) && Clientes[i].Clave.Equals(clave)))
                i++;

            if (i < Clientes.Count)
                return Clientes[i];
            else
                return null;
        }

        public Cliente buscarCliente(int dni)
        {
            int i = 0;

            while (i < Clientes.Count && !Clientes[i].Dni.Equals(dni))
                i++;

            if (i < Clientes.Count)
                return Clientes[i];
            else
                return null;
        }

        public void eliminarPorVencimiento()
        {
            for (int i = 0; i < reservas.Count; i++)
            {
                if (reservas[i].Fecha > DateTime.Now.AddDays(10))
                {
                    reservas[i].TipoOp = "";
                    reservas[i].eliminarseBD();
                    reservas.Remove(reservas[i]);
                }
            }
        }

        public void elminarCliente(Cliente dato)
        {
            Clientes.Remove(dato);
        }

        public void eliminarInmueble(Inmueble dato)
        {
            Inmuebles.Remove(dato);
        }

        public void eliminarreservas()
        {
            Reservas.Clear();
        }

        public void eliminaralquileres()
        {
            Alquileres.Clear();
        }

        public void eliminarventas()
        {
            Ventas.Clear();
        }

        public float Calcular(int mes)
        {
            float total = 0;

            for (int i = 0; i < Ventas.Count; i++)
                if (Ventas[i].Fecha.Month == mes)
                    total += Ventas[i].Monto * (float)0.03;

            for (int i = 0; i < Alquileres.Count; i++)
                if (Alquileres[i].Fecha.Month == mes)
                    total += (Alquileres[i].Monto * 3);

            return (total);
        }

        public static Inmobiliaria CrearInmobiliaria()
        {
            ArrayList d = new ArrayList();
            Inmobiliaria c = new Inmobiliaria();

            c.ArmarInmobiliaria(d);

            return c;

        }

        public bool ArmarInmobiliaria(ArrayList datosCurso)
        {
            bool ok = true;

            ArrayList inmuebles = new ArrayList();
            Inmueble inmueble;
            if (Datos.RecuperarInmuebles(inmuebles))
            {
                foreach (ArrayList inmu in inmuebles)
                {
                    inmueble = new Inmueble();
                    inmueble.armarObjeto(inmu);
                    this.agregarInmueble(inmueble);
                }
            }

            ArrayList clientes = new ArrayList();
            Cliente cliente;
            if (Datos.RecuperarClientes(clientes))
            {
                foreach (ArrayList cli in clientes)
                {
                    cliente = new Cliente();
                    cliente.armarObjeto(cli);
                    this.agregarCliente(cliente);
                }
            }

            ArrayList operaciones = new ArrayList();

            if (Datos.RecuperarOperaciones(operaciones))
            {
                foreach (ArrayList op in operaciones)
                {
                    if (op[5].ToString() == "Alquiler")
                    {
                        Alquiler alq = new Alquiler();
                        alq.armarObjeto(op);

                        this.agregarAlquiler(alq);
                    }

                    if (op[5].ToString() == "Venta")
                    {
                        Venta vent = new Venta();
                        vent.armarObjeto(op);

                        this.agregarVenta(vent);
                    }

                    if (op[5].ToString() == "Reserva")
                    {
                        Reserva res = new Reserva();
                        res.armarObjeto(op);

                        this.agregarReserva(res);
                    }
                }
            }

            return ok;
        }

        public int darContadorInmuebles()
        {
            if (inmuebles.Count > 0)
            {
                int max = inmuebles[0].Numero;

                for (int i = 0; i < inmuebles.Count; i++)
                    if (inmuebles[i].Numero > max)
                        max = inmuebles[i].Numero;

                return max + 1;
            }
            else
                return 1;
        }

        public int darContadorOperaciones()
        {
            int max = 0;

            if (alquileres.Count > 0 || ventas.Count > 0 || reservas.Count > 0)
            {
                if (alquileres.Count > 0)
                    max = alquileres[0].Numero;
                else if (ventas.Count > 0)
                    max = ventas[0].Numero;
                else
                    max = reservas[0].Numero;

                for (int i = 0; i < alquileres.Count; i++)
                    if (alquileres[i].Numero > max)
                        max = alquileres[i].Numero;

                for (int i = 0; i < ventas.Count; i++)
                    if (ventas[i].Numero > max)
                        max = ventas[i].Numero;

                for (int i = 0; i < reservas.Count; i++)
                    if (reservas[i].Numero > max)
                        max = reservas[i].Numero;

                return max + 1;
            }
            else
                return 1;
        }

        public List<Inmueble> listarEnVentaOAlquiler(string tipoOp, object obj)
        {

            List<Inmueble> disponibles = new List<Inmueble>();
            List<Inmueble> enTipoOp = new List<Inmueble>();
            disponibles = listarInmueblesDisponibles();
            Cliente cliente = (Cliente)obj;

            for (int i = 0; i < disponibles.Count; i++)
            {
                if (disponibles[i].TipoOperacion.Equals(tipoOp) || disponibles[i].TipoOperacion.Equals("Ambos"))
                {
                        enTipoOp.Add(disponibles[i]);
                }           
            }
          
            for (int i = 0; i < reservas.Count; i++)
            {
                if (reservas[i].Cliente.Equals(cliente.Dni))
                {
                   if ((buscarInmueble(reservas[i].Inmueble)).TipoOperacion.Equals(tipoOp) || (buscarInmueble(reservas[i].Inmueble)).TipoOperacion.Equals("Ambos"))
                    enTipoOp.Add(buscarInmueble(reservas[i].Inmueble));
                }
            }
            return enTipoOp;
        }

        public void indicarReserva(int numero)
        {
            Inmueble inm = new Inmueble();
            inm = buscarInmueble(numero);
            inm.Reservado = true;            
        }
    }
}

